package com.ruoyi.common.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.PtDDLFieldEntity;
import com.ruoyi.common.core.domain.entity.PtDDLTableEntity;
import com.ruoyi.common.core.domain.entity.PtDMLParam;
import com.ruoyi.common.enums.FieldType;
import com.ruoyi.common.enums.UnitType;
import com.ruoyi.common.mapper.PtDDLMapper;
import com.ruoyi.common.service.DDLService;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.sql.SqlUtil;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class DDLServiceImpl implements DDLService {

    @Autowired
    private PtDDLMapper ptDDLMapper;

    @Override
    public AjaxResult createTable(PtDDLTableEntity table) {
        String tableName = table.getTableName();
        String tableCommon = table.getTableCommon();
        ptDDLMapper.createTable(tableName, tableCommon);
        return AjaxResult.success("新增表成功");
    }

    @Override
    public AjaxResult createField(String tableName, List<PtDDLFieldEntity> fields) {
        SqlUtil.distinct(fields);
        List<String> alterSql = fields
                .stream()
                .map(x -> {
                    // alter table `${tableName}` add ${} varchar(50) null comment '名称';
                    StringBuilder sb = new StringBuilder("alter table");
                    sb.append(" `");
                    sb.append(tableName);
                    sb.append("` ");
                    sb.append("add ");
                    sb.append(x.getFieldName());
                    sb.append(" ");
                    sb.append(x.getFieldType().getType());
                    if (x.getFieldType().compareTo(FieldType.VARCHAR) == 0 &&
                            x.getFieldLength() != null &&
                            x.getFieldLength() > 0) {
                        sb.append("(" + x.getFieldLength() + ")");
                    }
                    if (x.getNil()) {
                        sb.append(" null");
                    } else {
                        sb.append(" not null");
                    }
                    sb.append(" comment ");
                    sb.append("'" + x.getFieldCommon() + "';");
                    return sb.toString();
                })
                .collect(Collectors.toList());

        alterSql.forEach(ptDDLMapper::createField);
        return AjaxResult.success("操作表字段成功");
    }

    @Override
    public AjaxResult createTableAndField(PtDDLTableEntity table, List<PtDDLFieldEntity> entities) {
        createTable(table);
        createField(table.getTableName(), entities);
        return AjaxResult.success();
    }

    @Override
    public AjaxResult dropTable(String tableName) {
        Map<String, Object> map = ptDDLMapper.dropTable(tableName);
        return null;
    }

    @Override
    public List<Map<String, Object>> list(String table) {
        return list(table, null, null);
    }

    @Override
    public List<Map<String, Object>> list(String table, List<PtDMLParam> params, String fieldList) {
        if (StringUtils.isEmpty(fieldList)) {
            fieldList = "*";
        }
        return ptDDLMapper.list(table, getParamList(params), fieldList);
    }

    @Override
    public int insert(String tableName, List<Map<String, Object>> data) {
        if (CollectionUtil.isEmpty(data)) {
            return 0;
        }
        data.forEach(x -> x.put("id", IdUtil.getSnowflakeNextId()));
        for (Map<String, Object> datum : data) {
            for (Map.Entry<String, Object> entry : datum.entrySet()) {
                if (entry.getValue() instanceof String) {
                    datum.put(entry.getKey(), "'" + entry.getValue() + "'");
                }
            }
        }
        return ptDDLMapper.insert(tableName, data.get(0).keySet(), data);
    }

    @Override
    public int delete(String tableName, List<PtDMLParam> params) {
        return ptDDLMapper.delete(tableName, getParamList(params));
    }

    @Override
    public Long count(String tableName) {
        List<Map<String, Object>> list = list(tableName, null, "count(*) as count");
        return MapUtil.getLong(list.get(0), "count");
    }

    @Override
    public int update(String tableName, List<Map<String, Object>> data, Map<String, Object> where) {
        return ptDDLMapper.update(tableName, data, where);
    }

    private List<String> getParamList(List<PtDMLParam> param) {
        if (CollectionUtil.isEmpty(param)) {
            return null;
        }
        List<String> where = new ArrayList<>();
        for (PtDMLParam dmlParam : param) {
            UnitType unit = dmlParam.getUnit();
            String field = dmlParam.getField();
            Object data = dmlParam.getData();
            String sql = field + unit.getDeUnit();
            if (data == null) {
                if (unit.compareTo(UnitType.NIL) == 0) {
                    sql = field + " " + unit.getDeUnit();
                } else {
                    sql = "";
                }
            } else if (data instanceof String) {
                sql += "'" + data + "'";
            } else if (data instanceof Integer || data instanceof Long) {
                sql += data;
            } else if (data instanceof Double) {
                sql += data;
            } else {
                sql += data;
            }
            where.add(sql);
        }
        return where;
    }
}
